home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / media / objects / converte / poly2off.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-03  |  4.0 KB  |  188 lines

  1. /* Convert Triangulated Poly files (TPOLY object format) 
  2.  * to indexed polygons in the 3-D Object File Format (OFF)
  3.  *
  4.  * POLY2OFF by Jason Mathews
  5.  *   NASA/Goddard Space Flight Center
  6.  *   Greenbelt, MD 20771
  7.  *   e-mail: mathews@nssdca.gsfc.nasa.gov (Internet)
  8.  *
  9.  * usage: poly2off [max_number_polygons] < tpoly_infile > off_outfile
  10.  *
  11.  * Modification history:
  12.  *   31-Mar-94 Original version (for unix platforms).
  13.  *
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <memory.h>
  19. #include <search.h>
  20.  
  21. #define DEF_POLYS 10000  /* default # of polygons */
  22. #define MAXPTS     9000  /* maximal allowable data points */
  23. #define MAXEDGES  10000  /* maximal number of edges */
  24.  
  25. /* types and structures */
  26.  
  27. typedef unsigned int uint;
  28.  
  29. typedef struct {
  30.   float x, y, z;
  31. } Point;
  32.  
  33. typedef struct {
  34.   uint v1, v2;
  35. } Edge;
  36.  
  37. int ptcmp( void* arg1, void* arg2 )
  38. {
  39.   return memcmp(arg1, arg2, sizeof(Point));
  40. }
  41.  
  42. int edgecmp( void* arg1, void* arg2 )
  43. {
  44.   return memcmp(arg1, arg2, sizeof(Edge));
  45. }
  46.  
  47. void usage()
  48. {
  49.   fprintf(stderr, "Usage:    poly2off [max_number_polygons]\n\n");
  50.   fprintf(stderr, "Defaults: number of polygons = %u\n", DEF_POLYS);
  51.   fprintf(stderr, "\t  number of points = %u\n\n", MAXPTS);
  52.   fprintf(stderr, "Example:  poly2off < teapot.tpoly > teapot.off\n");
  53.   exit(1);
  54. }
  55.  
  56. void MakeEdge( Edge* e, uint v1, uint v2 )
  57. {
  58.   if (v1 > v2)
  59.     {
  60.       uint tmp=v1; v1=v2; v2=tmp;
  61.     }
  62.   e->v1=v1; e->v2=v2;
  63. }
  64.  
  65. int main( int argc, char** argv )
  66. {
  67.   uint i, j;
  68.   int  npts;
  69.   long nLines    = 0;
  70.   uint nPoints   = 0;
  71.   uint nPolygons = 0;
  72.   uint nEdges    = 0;
  73.   uint maxPlanes = DEF_POLYS;
  74.   uint** planes;
  75.   Point points[MAXPTS];
  76.   Edge  edgeList[MAXEDGES];
  77.   
  78.   if (argc == 2)
  79.     {
  80.       maxPlanes = atoi(argv[1]);
  81.       if (!maxPlanes) usage();
  82.     }
  83.   
  84.   planes = (uint **) malloc( maxPlanes * sizeof(uint*));
  85.   if (!planes)
  86.     {
  87.       perror("poly2off");
  88.       return 1;
  89.     }
  90.   
  91.   while (scanf("%d", &npts) == 1)
  92.     {
  93.      uint old_pt; 
  94.       if (npts <= 0)
  95.     {
  96.       fprintf(stderr, "error: invalid number of points at line %ld\n",
  97.           nLines);
  98.       break;
  99.     }
  100.       nLines++;
  101.       planes[nPolygons] = (uint*) malloc( (npts+1) * sizeof(uint));
  102.       if (!planes[nPolygons]) 
  103.     {
  104.       perror("poly2off");
  105.       return 1;
  106.     }
  107.  
  108.       /* the first element contains the # of verticies in the polygon */
  109.       planes[nPolygons][0] = npts;
  110.       
  111.       for (i=1; i <= npts; i++)
  112.     {
  113.       Point pt;
  114.       Point* result;
  115.       size_t count = nPoints, idx;
  116.       
  117.       if (scanf("%f %f %f", &pt.x, &pt.y, &pt.z) != 3)
  118.         {
  119.           fprintf(stderr, "error: invalid points at line %ld\n", nLines);
  120.           return 1;
  121.         }
  122.       
  123.       result = (Point*) lsearch(&pt, points, &count,
  124.                     sizeof(Point), ptcmp);
  125.  
  126.       /* vertex index starts from 1, not 0 */
  127.  
  128.       if (count == nPoints)
  129.         {
  130.           idx = (uint) (result - points)+1; /* index of point */
  131.         }
  132.       else {
  133.          /* new point added to table */
  134.         if ((idx = ++nPoints) >= MAXPTS-1)
  135.           {
  136.         fprintf(stderr, "error: too many points\n\n");
  137.         usage();
  138.           }
  139.       }
  140.       
  141.       planes[nPolygons][i] = idx;
  142.       nLines++;
  143.     } /* for */
  144.  
  145.      /* check edges formed by polygon */
  146.      old_pt = planes[nPolygons][npts];
  147.      for (i=1; nEdges < MAXEDGES && i <= npts; i++)
  148.        {
  149.      uint idx = planes[nPolygons][i];
  150.      if (old_pt != idx)
  151.        {
  152.          Edge e;
  153.          size_t count = nEdges;
  154.          MakeEdge(&e, old_pt, idx);
  155.          lsearch(&e, edgeList, &count, sizeof(Edge), edgecmp);
  156.          if (count != nEdges) nEdges++;  /* new edge added */
  157.        }
  158.      old_pt = idx;
  159.        } /* for each point */
  160.  
  161.      if (++nPolygons > maxPlanes)
  162.        {
  163.      fprintf(stderr, "error: too many polygons: specify max parameter large enough\n\n");
  164.      usage();
  165.        }
  166.    } /* while */
  167.  
  168.   /*
  169.    *   print object in Object File Format (OFF)
  170.    */
  171.  
  172.   printf("%u %u %u\n", nPoints, nPolygons, nEdges);
  173.   for (i=0; i < nPoints; i++)
  174.     {
  175.       printf("%g %g %g\n",  points[i].x, points[i].y, points[i].z);
  176.     }
  177.   
  178.   for (i=0; i < nPolygons; i++)
  179.     {
  180.       printf("%u", planes[i][0]);
  181.       for (j=1; j <= planes[i][0]; j++)
  182.     printf(" %u", planes[i][j]);
  183.       printf("\n");
  184.     }
  185.  
  186.   return 0; /* okay */
  187. }
  188.